using PKGames.Voxel;
using System;
using System.Collections.Generic;
using UnityEngine;

namespace PKGames
{
	public class WindowsManager : MonoBehaviour
	{
		[SerializeField]
		private Canvas _windowCanvas;

		[Tooltip("Resources popup prefabs base path")]
		[SerializeField]
		private string _windowPrefabsPath = "window/";

		[Tooltip("GameObject with a canvas group to help with transitions")]
		[SerializeField]
		private GameObject _windowHolderPrefab;

		[Tooltip("This list contains all windows that will be added")]
		private List<GameObject> _windowHolderList;

		private const string PopupEspecialCaseKey = "AskForReviewWindow";

		private static WindowsManager _instance;

		public static WindowsManager Instance
		{
			get
			{
				if (_instance == null)
				{
					_instance = (WindowsManager)UnityEngine.Object.FindObjectOfType(typeof(WindowsManager));
				}
				return _instance;
			}
		}

		private void Awake()
		{
			if (base.transform.parent == null)
			{
				UnityEngine.Object.DontDestroyOnLoad(this);
			}
			_windowHolderList = new List<GameObject>();
		}

		public void ShowWindow<T>(bool destroyLastWindow, bool disableLastWindow, params object[] args) where T : AbstractWindow
		{
			GameObject windowHolder = CreateWindowHolder<T>();
			GameObject windowPrefabCopy = LoadWindowFromResources<T>();
			SetupPrefabWindow(windowPrefabCopy, windowHolder, args);
			ShowWindow(windowHolder, windowPrefabCopy, destroyLastWindow, disableLastWindow);
		}

		private GameObject CreateWindowHolder<T>() where T : AbstractWindow
		{
			GameObject gameObject = UnityEngine.Object.Instantiate(_windowHolderPrefab, _windowCanvas.transform);
			gameObject.name = "WindowHolder - " + typeof(T).FullName;
			return gameObject;
		}

		private GameObject LoadWindowFromResources<T>() where T : AbstractWindow
		{
			UnityEngine.Object[] array = Resources.LoadAll(_windowPrefabsPath, typeof(T));
			if (array == null || array.Length <= 0)
			{
				return null;
			}
			T val = array[0] as T;
			GameObject result = UnityEngine.Object.Instantiate(val.gameObject);
			Resources.UnloadUnusedAssets();
			return result;
		}

		private void SetupPrefabWindow(GameObject windowPrefabCopy, GameObject windowHolder, params object[] args)
		{
			AbstractWindow component = windowPrefabCopy.GetComponent<AbstractWindow>();
			Action<AbstractWindow, bool> closeWindow = CloseWindow;
			Action<GameObject> destroyWindow = DestroyWindow;
			component.SetupWindow(windowHolder, closeWindow, destroyWindow, args);
		}

		private void ShowWindow(GameObject windowHolder, GameObject windowPrefabCopy, bool destroyLastWindow, bool disableLastWindow)
		{
			windowPrefabCopy.transform.SetParent(windowHolder.transform, worldPositionStays: false);
			_windowHolderList.Add(windowHolder);
			RunTransitionIfAvailable(windowHolder, windowPrefabCopy, destroyLastWindow, disableLastWindow);
		}

		private void RunTransitionIfAvailable(GameObject windowHolder, GameObject windowPrefabCopy, bool destroyLastWindow, bool disableLastWindow)
		{
			AbstractWindow component = windowPrefabCopy.GetComponent<AbstractWindow>();
			if (!(component.WindowTransition == null))
			{
				windowHolder.SetActive(value: false);
				AbstractWindow stackSecondFromTop = GetStackSecondFromTop();
				WindowTransitionController.Instance.RunOpenPageTransition(stackSecondFromTop, component, destroyLastWindow, disableLastWindow);
			}
		}

		private AbstractWindow GetStackSecondFromTop()
		{
			if (_windowHolderList != null && _windowHolderList.Count > 1)
			{
				return _windowHolderList[_windowHolderList.Count - 2].GetComponentInChildren<AbstractWindow>();
			}
			return null;
		}

		private void CloseWindow(AbstractWindow abstractWindow, bool ignoreTransition)
		{
			if (abstractWindow.WindowTransition != null && !ignoreTransition)
			{
				AbstractWindow stackSecondFromTop = GetStackSecondFromTop();
				WindowTransitionController.Instance.RunClosePageTransition(abstractWindow, stackSecondFromTop);
			}
			else
			{
				abstractWindow.DestroyWindow();
			}
			ReactivateAudioIfNoWindowsAreOpen();
		}

		private void DestroyWindow(GameObject windowHolder)
		{
			_windowHolderList.Remove(windowHolder);
			UnityEngine.Object.Destroy(windowHolder);
		}

		private void ReactivateAudioIfNoWindowsAreOpen()
		{
			if (GetNumberOfOpenWindows() == 0 && Instance.GetNumberOfOpenWindows() != 0)
			{
			}
		}

		public void CloseAllWindows(Action OnFinish = null)
		{
			for (int num = _windowHolderList.Count - 1; num >= 0; num--)
			{
				_windowHolderList[num].GetComponentInChildren<AbstractWindow>().CloseWindow(ignoreTransition: true);
			}
			if (ApplicationManager.GetScreenOrientation() == ScreenOrientation.Portrait)
			{
				Screen.orientation = ScreenOrientation.LandscapeLeft;
			}
			OnFinish.Fire();
			ReactivateAudioIfNoWindowsAreOpen();
		}

		public int GetNumberOfOpenWindows()
		{
			return _windowHolderList.Count;
		}
	}
}
